package io.gitee.capricorn.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import io.gitee.capricorn.entity.JwtHeader;
import io.gitee.capricorn.entity.JwtPayload;
import io.gitee.gemini.utis.BeanUtil;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class JwtUtil {

    /**
     * jwt密钥 必须大于32个字符
     */
    private static String TOKEN_KEY = "54f12048-1f56-45c1-a3f1-2c546bc2bb42";

    /**
     * 加密算法
     */
    private static Algorithm ALGORITHM = Algorithm.HMAC256(TOKEN_KEY);
    /**
     * jwt有效时间
     */
    private static long TOKEN_TIMEOUT = 60 * 30 * 1000;

    /**
     * jwt生成方
     */
    private final static String JWT_ISSUER = "CAPRICORN";


    private JwtUtil() {
    }


    public static String createToken(JwtPayload payload) {
        if (payload.getExp() == null) {
            Date date = new Date(System.currentTimeMillis() + TOKEN_TIMEOUT);
            payload.setExp(date);
        }
        if (payload.getIss() == null) {
            payload.setIss(JWT_ISSUER);
        }
        Map<String, Object> payloadMap = BeanUtil.beanToMap(payload);
        JWTCreator.Builder builder = builder(null, payloadMap);
        String token = builder.sign(ALGORITHM);

        return token;
    }


    /**
     * 生成token
     *
     * @param header  jwt头信息
     * @param payload payload 载荷，可扩展 JwtPayload
     * @return token
     */
    public static String createToken(JwtHeader header, JwtPayload payload, Algorithm algorithm) {
        String token;
        header.setAlg(algorithm.getName());
        Map<String, Object> headerMap = BeanUtil.beanToMap(header);
        Map<String, Object> payloadMap = BeanUtil.beanToMap(payload);
        JWTCreator.Builder builder = builder(headerMap, payloadMap);
        token = builder.sign(algorithm);
        return token;
    }


    /**
     * 构建 jwt builder
     *
     * @param header  头
     * @param payload 载荷
     * @return
     */
    private static JWTCreator.Builder builder(Map<String, Object> header, Map<String, Object> payload) {
        JWTCreator.Builder builder = JWT.create()
                .withHeader(header)
                .withPayload(payload);
        return builder;
    }


    /**
     * 校验解密token
     *
     * @param token 需要解密的token
     * @return 可操作jwt对象
     */
    public static DecodedJWT decodeToken(String token) {
        DecodedJWT jwt;

        Algorithm algorithm = Algorithm.HMAC256(TOKEN_KEY);
        JWTVerifier verifier = JWT.require(algorithm)
                .build();
        jwt = verifier.verify(token);

        return jwt;
    }


    /**
     * 设置tokenkey 的长度
     *
     * @param tokenKey tokenkey 长度需大于32
     */
    public static void setTokenKey(CharSequence tokenKey) {
        TOKEN_KEY = tokenKey.toString();
        ALGORITHM = Algorithm.HMAC256(TOKEN_KEY);
    }

    /**
     * 设置超时时间
     *
     * @param time     时间
     * @param timeUnit 单位
     */
    public static void setTokenTimeout(long time, TimeUnit timeUnit) {
        TOKEN_TIMEOUT = timeUnit.toMillis(time);
    }


}
